﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.IO;
using System.Drawing.Imaging;
using QlrrPrintService.Common.Extension;
using System.Net;

namespace QlrrPrintService.Common.Command
{
    public class BitmapCommand : PrintLocation,IToTSPLCommand
    {

        #region 构造函数

        public BitmapCommand() { }

        //public PrintBitmap(int x, int y, int width, int height, byte[] bitmapData)
        //    :base(x,y)
        //{
       
        //    _width = width;
        //    _height = height;
        //}

        #endregion

        #region 变量

        protected byte[] _commandData;

        protected string _commandline = null;

        /// <summary>
        /// 图像的高圖形的寬度，單位為 byte
        /// </summary>
        protected int _width;

        /// <summary>
        /// 圖形的高度，單位為 dot
        /// </summary>
        protected int _height;


        /// <summary>
        /// bitmap数据
        /// </summary>
        protected byte[] _bitmapData;

        protected int _rotation = 0;

        

        /// <summary>
        /// 水平旋转或垂直旋转
        /// </summary>
        protected string _vhRotation = null;
        

      

        /// <summary>
        /// 绘制原形的方式
        /// 0 OVERWRITE
        /// 1 OR
        /// 2 XOR
        /// </summary>
        private int _mode = 0;

        private string _base64Code;

        private string _url;

        #endregion

        #region 属性

        [Newtonsoft.Json.JsonIgnore]
        protected byte[] BitmapData
        {
            get 
            {
                return _bitmapData;
            }
          
        }

        public string url
        {
            get { return _url; }

            set 
            {
                _url = value;

                try
                {
                    WebRequest request = WebRequest.Create(_url);
                    WebResponse response = request.GetResponse();
                    if (response != null)
                    {

                        Stream stream = response.GetResponseStream();
                        byte[] bytes = new byte[stream.Length];
                        stream.Read(bytes, 0, bytes.Length);
                        // 设置当前流的位置为流的开始
                        stream.Seek(0, SeekOrigin.Begin);
                        Convert.ToBase64String(bytes);

                    }
                }
                catch
                { }

            }
        }

        public int Rotation
        {
            get { return _rotation; }
            set { _rotation = value; }
        }

        public string Base64Code
        {
            get { return _base64Code; }
            set
            {
                _base64Code = value;

            }
        }

        public string VHRotation
        {
            get { return _vhRotation; }
            set { _vhRotation = value; }
        }

        protected int Width
        {
            get { return _width; }
          
            
        }
        

        protected int Height
        {
            get { return _height; }

            
        }

       
        public int Mode
        {
            get { return _mode; }
            set { _mode = value; }
        }

        #endregion

        #region 受保护函数



        //protected  Bitmap ColorToGrayscale(Bitmap bmp)
        //{
        //        int w = bmp.Width,
        //        h = bmp.Height,
        //        r, ic, oc, bmpStride, outputStride, bytesPerPixel;
        //        PixelFormat pfIn = bmp.PixelFormat;
        //        ColorPalette palette;
        //        Bitmap output;
        //        BitmapData bmpData, outputData;

        //        //Create the new bitmap
        //        output = new Bitmap(w, h, PixelFormat.Format8bppIndexed);

        //        //Build a grayscale color Palette
        //        palette = output.Palette;
        //        for (int i = 0; i < 256; i++)
        //        {
        //            Color tmp = Color.FromArgb(255, i, i, i);
        //            palette.Entries[i] = Color.FromArgb(255, i, i, i);
        //        }
        //        output.Palette = palette;

        //        //No need to convert formats if already in 8 bit
        //        if (pfIn == PixelFormat.Format8bppIndexed)
        //        {
        //            output = (Bitmap)bmp.Clone();

        //            //Make sure the palette is a grayscale palette and not some other
        //            //8-bit indexed palette
        //            output.Palette = palette;

        //            return output;
        //        }

        //        //Get the number of bytes per pixel
        //        switch (pfIn)
        //        {
        //            case PixelFormat.Format24bppRgb: bytesPerPixel = 3; break;
        //            case PixelFormat.Format32bppArgb: bytesPerPixel = 4; break;
        //            case PixelFormat.Format32bppRgb: bytesPerPixel = 4; break;
        //            default: throw new InvalidOperationException("Image format not supported");
        //        }

        //        //Lock the images
        //        bmpData = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly,
        //        pfIn);
        //        outputData = output.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.WriteOnly,
        //        PixelFormat.Format8bppIndexed);
        //        bmpStride = bmpData.Stride;
        //        outputStride = outputData.Stride;

        //        //Traverse each pixel of the image
        //        unsafe
        //        {
        //            byte* bmpPtr = (byte*)bmpData.Scan0.ToPointer(),
        //            outputPtr = (byte*)outputData.Scan0.ToPointer();

        //            if (bytesPerPixel == 3)
        //            {
        //                //Convert the pixel to it's luminance using the formula:
        //                // L = .299*R + .587*G + .114*B
        //                //Note that ic is the input column and oc is the output column
        //                for (r = 0; r < h; r++)
        //                    for (ic = oc = 0; oc < w; ic += 3, ++oc)
        //                        outputPtr[r * outputStride + oc] = (byte)(int)
        //                        (0.299f * bmpPtr[r * bmpStride + ic] +
        //                        0.587f * bmpPtr[r * bmpStride + ic + 1] +
        //                        0.114f * bmpPtr[r * bmpStride + ic + 2]);
        //            }
        //            else //bytesPerPixel == 4
        //            {
        //                //Convert the pixel to it's luminance using the formula:
        //                // L = alpha * (.299*R + .587*G + .114*B)
        //                //Note that ic is the input column and oc is the output column
        //                for (r = 0; r < h; r++)
        //                    for (ic = oc = 0; oc < w; ic += 4, ++oc)
        //                        outputPtr[r * outputStride + oc] = (byte)(int)
        //                        ((bmpPtr[r * bmpStride + ic] / 255.0f) *
        //                        (0.299f * bmpPtr[r * bmpStride + ic + 1] +
        //                        0.587f * bmpPtr[r * bmpStride + ic + 2] +
        //                        0.114f * bmpPtr[r * bmpStride + ic + 3]));
        //            }
        //        }

        //        //Unlock the images
        //        bmp.UnlockBits(bmpData);
        //        output.UnlockBits(outputData);

        //        return output;
        //}

        //protected byte[] ConvertTo24bpp()
        //{

        //    try
        //    {
        //        if (_base64Code != null)
        //        {
        //            var imgBytes = Convert.FromBase64String(_base64Code);
        //            using (var steam = new System.IO.MemoryStream(imgBytes))
        //            {
        //                var img = Bitmap.FromStream(steam) as Bitmap;
        //                if (img != null)
        //                {
        //                    var bmp = ColorToGrayscale(img);
        //                    _width = bmp.Width;
        //                    _height = bmp.Height;
        //                    using (MemoryStream ms = new MemoryStream())
        //                    {
        //                        bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
        //                        return ms.GetBuffer();
                                
        //                    }
        //                }
        //            }
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        throw ex;
        //    }
        //    return null;
            
        //}

        #endregion

        #region IToTSPLCommand 成员

        public byte[] ToTSPLCommandByte(int mm_to_dot)
        {
            if (_commandData == null && _base64Code!=null)
            {
                var bmp = _base64Code.Base64StrToBitmap();
                Bitmap vBmp = null;
                
                if (bmp != null)
                {
                    //bmp = bmp.RotateImg(_rotation);
                    if (_vhRotation != null)
                    {
                        var rType = _vhRotation.ToLower();
                        if (rType == "v")
                        {
                            vBmp = bmp.VerticalRoation(bmp.Width, bmp.Height);
                        }
                        else if (rType == "h")
                        {
                            vBmp = bmp.HorizontalRoation(bmp.Width, bmp.Height);
                        }
                    }
                    else
                    {
                        vBmp = bmp;
                    }
                    if (vBmp != null)
                    {
                        var onebppBmp = vBmp.ConvertTo1bppOr8bpp(1);
                        if (onebppBmp != null)
                        {

                            _width = onebppBmp.Width;
                            _height = onebppBmp.Height;
                            _bitmapData = onebppBmp.BmpToByteArray();
                        }
                    }
                    
                }
                else
                {
                    return null;
                }

                if (_bitmapData != null)
                {
                    string head = string.Format("BITMAP {0},{1},{2},{3},{4},",
                       _x * mm_to_dot, _y * mm_to_dot, (int)Math.Ceiling(Convert.ToDecimal(_width) / 8), _height, _mode);
                    var commandHead = System.Text.ASCIIEncoding.ASCII.GetBytes(head);
                    _commandData = new byte[commandHead.Length + _bitmapData.Length + 2];
                    Array.Copy(commandHead, _commandData, commandHead.Length);
                    int index = commandHead.Length;
                    Array.Copy(_bitmapData, 0, _commandData, index, _bitmapData.Length);
                    index += _bitmapData.Length;
                    Array.Copy(Common.TSPL_END_BYTE, 0, _commandData, index, Common.TSPL_END_BYTE.Length);
                }
               
            }
            return _commandData;
        }

        public string ToTSPLCommandAscii(int mm_to_dot)
        {
            if (_commandline == null)
            {
                var command=ToTSPLCommandByte(mm_to_dot);
                if (command != null)
                {
                    _commandline = System.Text.ASCIIEncoding.ASCII.GetString(command);
                }
            }
            return _commandline;

            
            
        }

        #endregion
    }
}
